import { chain } from 'ramda';

import { DatasetListItem, DatasetTypeEnum } from '@/common';
import { TreeData } from '@/types/dataset';

/**
 * Flatten an array containing a tree structure
 * @param {T[]} trees - An array containing a tree structure
 * @returns {T[]} - Flattened array
 */
export function flattenTrees<T extends { children?: T[] }>(trees: T[] = []): T[] {
  return chain((node) => {
    const children = node.children || [];
    return [node, ...flattenTrees(children)];
  }, trees);
}

/**
 * 将树形数据拆分为不包含 children 的对象列表（保留每个节点的所有原始字段）
 */
export function treeToPlainList<T extends Record<string, any>>(data: T | T[] = []): T[] {
  const arr = Array.isArray(data) ? data : [data];
  const flat = flattenTrees<T>(arr);
  return flat.map((node) => {
    const { children, ...rest } = node as any;
    return { ...rest } as T;
  });
}

export function getNodeParent(tree: TreeData[], node: TreeData): void {
  if (node.parent) {
    tree.push(node.parent);
    getNodeParent(tree, node.parent);
  }
}

export function getNodeParentType(node: TreeData | undefined, type: string): TreeData | null {
  if (!node) {
    return null;
  }
  if (node.type == type) {
    return node;
  }
  return getNodeParentType(node.parent, type);
}

export function transformToTreeItems(
  datasets: DatasetListItem[],
  parent: TreeData | undefined,
  filter: false,
): TreeData[] {
  // const datas = filter ? datasets.filter((item) => item.type !== 'file') : datasets;
  const datas = datasets;

  return datas.map((item) => {
    const currentItem: TreeData = {
      ...item,
      // key: item.fileId !== undefined ? item.fileId : item._id || item.id,
      key: item._id || item.id || item.fileId, // 这个用于请求的发送
      title: item.name || item.fileName,
      type: item.type === 'faq' ? 'dataset' : item.type,
      // type: item.type,
      fileId: item.fileId,
      parentKey: parent ? parent.id : item.parentId,
      parent,
      name: item.name || item.fileName,
      updateTime: item.updateTime,
      // count: item.count ?? 100,
      forbid: item.forbid || false,
    };
    // const children = filter ? item.children?.filter((item) => item.type !== 'file') : item.children;
    // currentItem.children = children
    //   ? transformToTreeItems(children, currentItem, filter)
    //   : undefined;

    return currentItem;
  });
}

export function getNodeTypeName(node: TreeData | undefined): string {
  if (!node) {
    return '未知';
  }
  switch (node.type) {
    case 'dataset':
      return '知识库';
    case 'file':
      return '文件';
    case 'folder':
      return '文件夹';
    default:
      return '未知';
  }
}

export function getBackground(type: string): string {
  switch (type) {
    case DatasetTypeEnum.folder:
      return 'linear-gradient(136.17deg, #728AFF 0%, #8377FF 100%, #FF00FF 100%)';
    case DatasetTypeEnum.file:
      return 'transparent';
    case DatasetTypeEnum.api:
      return 'linear-gradient(136.17deg, #8377FF 0%, #27B5FF 100%, #FF00FF 100%)';
    default:
      return 'linear-gradient(136.17deg, #728AFF 0%, #B844FF 48.69%, #F705FF 91.91%)';
  }
}

export function filterTree(
  nodes: TreeData[],
  keyword: string,
  filterDatabase: boolean,
  filterType: string,
): TreeData[] {
  if (!keyword && !filterDatabase) {
    return nodes;
  }
  return nodes.reduce<TreeData[]>((filtered, node) => {
    const isMatch = node.name?.includes(keyword);
    if (node && filterType?.includes(node.type)) {
      return filtered;
    }

    const filteredChildren = node.children
      ? filterDatabase && node.type == 'dataset'
        ? []
        : filterTree(node.children, keyword, filterDatabase, filterType)
      : [];

    if (isMatch || filteredChildren.length > 0) {
      filtered.push({
        ...node,
        children: filteredChildren,
      });
    }

    return filtered;
  }, []);
}

export function findNodeById<T extends { children?: T[]; id?: string; _id?: string }>(
  nodes: T[] = [],
  targetId: string,
): T | undefined {
  const stack: T[] = [...nodes];

  while (stack.length > 0) {
    const node = stack.pop()!;

    if (node?.id === targetId || node?._id === targetId) {
      return node;
    }

    if (node.children) {
      stack.push(...node.children);
    }
  }
  return undefined;
}

export function findParentIdArray<T extends { children?: T[]; id?: string; _id?: string }>(
  nodes: T[] = [],
  targetId: string,
): string[] | undefined {
  const search = (role: T, items: string[]): string[] | undefined => {
    if (role.id == targetId || role?._id === targetId) {
      return items;
    }

    if (role.children) {
      for (const child of role.children) {
        const result = search(child, [...items, role?.id || role?._id || '']);
        if (result) {
          return result;
        }
      }
    }
    return undefined;
  };
  for (const node of nodes) {
    const result = search(node, []);
    if (result) {
      return result;
    }
  }
  return undefined;
}

export function findParentNameArray<T extends { children?: T[]; id?: string; _id?: string }>(
  nodes: T[] = [],
  targetId: string,
): string[] | undefined {
  const search = (role: T, items: string[]): string[] | undefined => {
    if (role.id == targetId || role?._id === targetId) {
      return items;
    }

    if (role.children) {
      for (const child of role.children) {
        const result = search(child, [...items, role?.name || role?.name || '']);
        if (result) {
          return result;
        }
      }
    }
    return undefined;
  };
  for (const node of nodes) {
    const result = search(node, []);
    if (result) {
      return result;
    }
  }
  return undefined;
}

// 递归处理函数
export function processData(data: any): any {
  // 如果是数组，遍历处理每个元素
  if (Array.isArray(data)) {
    // const res = data.filter((item) => item.system_code !== 'default'); 暂时去掉，FAQ属于未分组
    return data.map((item) => processData(item));
  }

  // 如果是对象，处理每个属性
  if (typeof data === 'object' && data !== null) {
    const newData = {
      ...data,
      // 添加新字段（示例）
      value: data.id,
      title: data.name,
      key: data.id,
    };

    // 递归处理子属性
    if (data.children) {
      newData.children = processData(data.children);
    }

    return newData;
  }

  // 非对象/数组直接返回
  return data;
}
